﻿#include "Qss.h"
#include <QPushButton>
#include <QLabel>
#include <QBoxLayout>
#include <QStyleOption>
#include <QPainter>
#include <QMouseEvent>
#include <QApplication>
#include <QDesktopWidget>
#include <QtMath>
#include <QPropertyAnimation>
#include <QParallelAnimationGroup>
#include <QDebug>
#include <QFile>
#include <QSizePolicy>
#include <QDesktopWidget>
#include "windows.h"
#include "winuser.h"
#include <QPropertyAnimation>
#include <QScreen>
#include <QGuiApplication>
#include <QPainter>
#include <QTimer>
#include <QCoreApplication>
#include <QGraphicsDropShadowEffect>
#include <QPainterPath>
#include <QAction>
#include <QPushButton>
#include <QLineEdit>
#include <QComboBox>
#include <QDateTimeEdit>
#include <QMenu>
#include <QMenuBar>

#define QSSDIALOG_SHADOW_WIDTH 12
#define QSSDIALOG_BODER_WIDTH 0

static void rangeObjectList(QObject*obj,int indent){
    QObjectList child = obj->children();
    QString tmp("");
    for(int i = 0;i < indent;i++)
        tmp +=" ";

    for(int i = 0;i < child.size();i++){
       qDebug()<<tmp + child.at(i)->objectName() + " " + child.at(i)->metaObject()->className();
       if(child.at(i)->children().size() > 0){
            rangeObjectList(child.at(i),indent + 1);
       }
    }
}

QssTtitleBar::QssTtitleBar(QWidget *parent ,
                           QTitleBar_Type type/* = QTitleBar_Type_Window*/)
    : QWidget(parent),
      m_Main(nullptr),
      m_maxOrRestore(false),
      m_pressed(false),
      m_type(type)
{
    setObjectName("qssTitleBar");
    m_closeBtn = new QPushButton(this);
    m_closeBtn->setObjectName("titlebarclosebtn");
    m_closeBtn->setToolTip(QString::fromLocal8Bit(""));
    m_closeBtn->setVisible(m_type & QTitleBar_Button_Close);

    m_minBtn = new QPushButton(this);
    m_minBtn->setObjectName("titlebarminbtn");
    m_minBtn->setToolTip(QString::fromLocal8Bit("最大化"));
    m_minBtn->setVisible(m_type & QTitleBar_Button_Min);

    m_restoreBtn = new QPushButton(this);//
    m_restoreBtn->setObjectName("titlebarrestorebtn");
    m_restoreBtn->setToolTip(QString::fromLocal8Bit(""));
    m_restoreBtn->setVisible(m_type & QTitleBar_Button_Restore);

    m_maxBtn = new QPushButton(this);//normal
    m_maxBtn->setObjectName("titlebarmaxbtn");//css
    m_maxBtn->setToolTip(QString::fromLocal8Bit(""));
    m_maxBtn->setVisible(m_type & QTitleBar_Button_Max);


    m_titlebarTitle = new QLabel(this);
    m_titlebarTitle->setObjectName("title");

    QHBoxLayout* hBox = new QHBoxLayout(this);

    hBox->setContentsMargins(0,0,0,0);

    hBox->addStretch(20);
    hBox->addWidget(m_titlebarTitle);
    hBox->addStretch(19);
    hBox->addWidget(m_minBtn);
    hBox->addWidget(m_restoreBtn);
    m_restoreBtn->setVisible(m_maxOrRestore);
    hBox->addWidget(m_maxBtn);
    hBox->addWidget(m_closeBtn);

    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    connect(m_closeBtn, SIGNAL(clicked()), parent, SLOT(close()));
    connect(m_minBtn, SIGNAL(clicked()), parent, SLOT(showMinimized()));
    connect(m_maxBtn, SIGNAL(clicked()), this, SLOT(onMaxOrRestore()));
    connect(m_restoreBtn, SIGNAL(clicked()), this, SLOT(onMaxOrRestore()));

    installEventFilter(this);

    m_rcValid = QApplication::desktop()->availableGeometry();

    setWindowFlags(windowFlags()|Qt::MSWindowsFixedSizeDialogHint);
    this->setGeometry(parent->geometry().x(),parent->geometry().y(),0,0);
    m_rcNormal = parentWidget()->geometry();

    QFile file(":/qss/css/QssTitleBar.css");
    if (!file.open(QIODevice::ReadOnly)){
        qDebug()<<"error bar";
    }
    QTextStream in(&file);
    QString css = in.readAll();
    this->setStyleSheet(css);
    m_titlebarTitle->setMinimumHeight(this->height());

}

QssTtitleBar::~QssTtitleBar()
{
    delete(this->m_maxBtn);
    delete(this->m_restoreBtn);
}

void QssTtitleBar::setTitle( QString title )
{
    m_titlebarTitle->setText(title);
}

void QssTtitleBar::setIcon( QIcon icon)
{
//    m_iconBtn->setIcon(icon);
}

void QssTtitleBar::setMaxOrRestore( bool val)
{
    m_maxOrRestore = val;//true
    if ((m_type & QTitleBar_Button_Restore) && (m_type & QTitleBar_Button_Max))
    {
        m_restoreBtn->setVisible(m_maxOrRestore);
        m_maxBtn->setVisible(!m_maxOrRestore);
    }
}

void QssTtitleBar::SetMainWindow(QMainWindow *p)
{
    if(nullptr ==p){
        return;
    }
    this->m_Main = p;
}

/** m_maxNormaltrue */
void QssTtitleBar::onMaxOrRestore()
{
    if (m_type != QTitleBar_Type_MainWindow)
        return ;
#ifdef QT_NO_EMIT
    OnMaxOrRestore(m_maxOrRestore);
#else
    emit(OnMaxOrRestore(m_maxOrRestore));
#endif

    setMaxOrRestore(!m_maxOrRestore);
}
void QssTtitleBar::paintEvent(QPaintEvent *)
{
    QStyleOption opt;
    opt.init(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

void QssTtitleBar::mouseMoveEvent( QMouseEvent * ev )
{
    if (m_maxOrRestore)
        return;
    if (!m_pressed)
        return;

    QPoint globalPt = ev->globalPos();
    QPoint movePt = globalPt - m_pressedPos;
    parentWidget()->move(movePt);
    QssMainWindow *parent = static_cast<QssMainWindow*>(parentWidget());
//    if(nullptr != parent){
//        parent->DetectDpiChange();
//    }
    return ;
}

void QssTtitleBar::mousePressEvent( QMouseEvent * ev )
{
    m_pressed = true;
    m_pressedPos = mapToParent(ev->pos());

    return ;
}

void QssTtitleBar::mouseReleaseEvent( QMouseEvent * ev )
{
    m_pressed = false;
}

bool QssTtitleBar::eventFilter( QObject * obj, QEvent * ev )
{
    if (obj == this)
    {
        if (ev->type() == QEvent::MouseButtonDblClick)
        {
            onMaxOrRestore();
            return true;
        }
    }
    return QWidget::eventFilter(obj, ev);
}

void QssMainWindow::OnMaxOrRestore(bool max)
{
    if (max)
    {
        setMinimumSize(0, 0);
        setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
        this->m_frame->setMinimumSize(0, 0);
        this->m_frame->setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));

        if (!m_rcNormal.isValid())
        {
            QSize sizeHint = parentWidget()->sizeHint();
            if (sizeHint.width() > m_rcValid.width())
                sizeHint.setWidth(m_rcValid.width() -100);
            if (sizeHint.height() > m_rcValid.height())
                sizeHint.setHeight(m_rcValid.height() - 100);

            m_rcNormal.setLeft((m_rcValid.width() - sizeHint.width())/2);
            m_rcNormal.setTop((m_rcValid.height() - sizeHint.height())/2);
            m_rcNormal.setWidth(sizeHint.width());
            m_rcNormal.setHeight(sizeHint.height());
        }

        this->parentWidget()->setGeometry(m_rcNormal);
        this->setGeometry(m_rcNormalCentral);
        setMinimumSize(0, 0);
        setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
        this->m_frame->setMinimumSize(0, 0);
        this->m_frame->setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
    }
    else
    {
        m_rcNormal = this->parentWidget()->geometry();
        m_rcNormalCentral = this->geometry();

        setMinimumSize(0, 0);
        setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
        this->m_frame->setMinimumSize(0, 0);
        this->m_frame->setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));

        QDesktopWidget desktop;
        QRect rc = desktop.availableGeometry(-1);

        parentWidget()->setGeometry(rc);
        rc.setRight(rc.right() - 50);

        this->setGeometry(rc);
        this->setFixedHeight(rc.height() - m_titleBar->height());
    }
}
// 实际测试切换分辨率会触发这个slot
void QssMainWindow::PhisycalDpiChange(qreal dpi)
{
    qDebug()<<"dpi changed,reason: configuration "<<dpi;

}
// 实际测试切换分辨率或者修改缩放比率都会触发这个slot
void QssMainWindow::LogicalDpiChange(qreal dpi)
{
    qDebug()<<"dpi changed,reason: configuration "<<dpi;
    m_dpi_ratio = 96/dpi;
    qDebug()<<"factor is "<<m_dpi_ratio;
//    auto parent = this->parentWidget();
//    parent->setGeometry(parent->geometry().x(),parent->geometry().y(),
//                      parent->geometry().width()*m_dpi_ratio,
//                      parent->geometry().height()*m_dpi_ratio);
}


QssMainWindow::QssMainWindow(QWidget *parent/* = 0*/, Qt::WindowFlags flags/* = 0*/,float scale)
: QMainWindow(parent, flags),
  m_mousePressedInBoundy(false),
  m_bLeftPress(false),
  m_dpi_ratio(1.0)
{
    QEvent::registerEventType();
    m_rcValid = QApplication::desktop()->availableGeometry();
    m_frame = new QFrame(parent, flags);
    m_frame->setObjectName("window");

    m_frame->setWindowFlags(Qt::Window |
                            Qt::FramelessWindowHint|
                            Qt::WindowSystemMenuHint |
                            Qt::WindowMinimizeButtonHint);
    m_frame->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);
    m_frame->setMouseTracking(true);
    m_frame->installEventFilter(this);
    m_titleBar = new QssTtitleBar(m_frame);
    m_titleBar->installEventFilter(this);
    m_titleBar->SetMainWindow(this);
    QVBoxLayout* vbox = new QVBoxLayout(m_frame);
    vbox->addWidget(m_titleBar);
    vbox->setMargin(1);
    vbox->setSpacing(0);
    vbox->addWidget(this);


    mFrameRect = m_frame->geometry();
    m_rcNormal = m_frame->geometry();
    m_rcNormalCentral = this->geometry();
    connect(this->titleBar(),SIGNAL( OnMaxOrRestore(bool )),this,SLOT(OnMaxOrRestore(bool)));
    QFile file(":/qss/css/QssMainWindow.css");
    if (!file.open(QIODevice::ReadOnly)){
        qDebug()<<"error bar";
    }
    QTextStream in(&file);
    QString css = in.readAll();
    qDebug()<<css;
    m_frame->setStyleSheet(css);

    mShadowMask = new  QWidget(this);
    mShadowMask->setStyleSheet("QWidget{background-color:rgba(1,1,1,0.3);}");
    mShadowMask->hide();

    int screenNum =  qApp->desktop()->screenNumber(this);
    mCurrentScreen = qApp->screens().at(screenNum);
    if(nullptr != mCurrentScreen){
        connect(mCurrentScreen,
                SIGNAL(physicalDotsPerInchChanged(qreal)),
                this,SLOT(PhisycalDpiChange(qreal)));

        connect(mCurrentScreen,
                SIGNAL(logicalDotsPerInchChanged(qreal)),
                this,SLOT(LogicalDpiChange(qreal)));
    }
//    rangeObjectList(m_frame,0);
    detectDpi();
    return;
}

QssMainWindow::~QssMainWindow()
{
    m_frame->deleteLater();
}

void QssMainWindow::AdapteDpi()
{
    QObjectList child = this->m_frame->children();
    int i = 0;
    for(int i = 0;i < child.size();i++){
       qDebug()<<child.at(i)->objectName() + " "
                 + child.at(i)->metaObject()->className();

      // QssTtitleBar
       if(child.at(i)->objectName() =="qssTitleBar"){
           QssTtitleBar *p = dynamic_cast<QssTtitleBar*>(child.at(i));
           if(nullptr != p){
               qDebug()<< p->sizePolicy();
               p->setFixedHeight(p->height()*m_dpi_ratio);
           }
       }
       if(child.at(i)->children().size() > 0){
            this->rangeObjectList(child.at(i),i + 1);
       }
    }
}

QWidget *QssMainWindow::TitleBar()
{
    return m_titleBar;
}

void QssMainWindow::RangeObject()
{
    rangeObjectList(m_frame,0);
}

void QssMainWindow::DetectDpiChange()
{
    int screenNum =  qApp->desktop()->screenNumber(this);
    auto currentScreen = qApp->screens().at(screenNum);

    if(currentScreen != mCurrentScreen){
        qDebug()<<"dpi change,reason screen changed";
        mCurrentScreen = currentScreen;
    }
}

void QssMainWindow::ShowMask()
{
    mShadowMask->setGeometry(0, 0, this->width(),this->height());    //遮罩窗口位置
    mShadowMask->show();
}

void QssMainWindow::HideMask()
{
    mShadowMask->hide();
}

void QssMainWindow::show()
{
    m_frame->show();
}

void QssMainWindow::showMinimized()
{
    m_frame->showMinimized();
}


enum {
    TOPLEFT = 11,
    TOP = 12,
    TOPRIGHT = 13,
    LEFT = 21,
    CENTER = 22,
    RIGHT = 23,
    BUTTOMLEFT = 31,
    BUTTOM = 32,
    BUTTOMRIGHT = 33
};

void QssMainWindow::setCursorShape(int CalPos)
{
    Qt::CursorShape cursor;
    switch(CalPos)
    {
    case TOPLEFT:
    case BUTTOMRIGHT:
        cursor = Qt::SizeFDiagCursor;
        break;
    case TOPRIGHT:
    case BUTTOMLEFT:
        cursor = Qt::SizeBDiagCursor;
        break;
    case TOP:
    case BUTTOM:
        cursor = Qt::SizeVerCursor;
        break;
    case LEFT:
    case RIGHT:
        cursor = Qt::SizeHorCursor;
        break;
    default:
        cursor = Qt::ArrowCursor;
        break;
    }
    setCursor(cursor);
}

void QssMainWindow::showMaximized()
{
    m_titleBar->setMaxOrRestore(true);
    m_frame->setGeometry(m_rcValid);
}

void QssMainWindow::showFullScreen()
{
    m_titleBar->setMaxOrRestore(true);
    m_frame->showFullScreen();
}

void QssMainWindow::showNormal()
{
    m_titleBar->setMaxOrRestore(false);
    m_frame->resize(rect().width(), rect().height() + m_titleBar->rect().height());
    m_frame->showNormal();
}

void QssMainWindow::setWindowTitle( QString title )
{
    m_titleBar->setTitle(title);
}

void QssMainWindow::setWindowIcon( QIcon icon )
{
    m_frame->setWindowIcon(icon);
    m_titleBar->setIcon(icon);
}
#define FRAMESHAPE 10

int QssMainWindow::CalCursorPos(QPoint pt, int colPos)
{
    return ((pt.y() < FRAMESHAPE ? 10 : ((pt.y() > this->height() - FRAMESHAPE) ? 30 : 20)) + colPos);
}

void QssMainWindow::SetTitleHeight(uint32_t height)
{
    this->m_titleBar->setFixedHeight(height);
}


int QssMainWindow::CalCursorCol(QPoint pt)
{
    return (pt.x() < FRAMESHAPE ? 1 : ((pt.x() > this->width() - FRAMESHAPE) ? 3 : 2));
}


void QssMainWindow::onMouseMoveEvent(QMouseEvent * ev)
{
    if (m_titleBar->maxOrRestore())
    {
        return;
    }
    if(Qt::WindowMaximized != windowState())
    {
       setCursorShape(CalCursorPos(ev->pos(),CalCursorCol(ev->pos())));
    }
    QPoint ptCurrentPos = QCursor::pos();
    QRect rtCentralGeo = this->centralWidget()->geometry();
    QRect rtMainWindow = this->geometry();
    setCursor(Qt::ArrowCursor);
    if (m_mousePressedInBoundy)
    {
        int x = ev->globalPos().x();
        int y = ev->globalPos().y();

        int dx = x - m_pos.x();
        int dy = y - m_pos.y();

        if ((m_left || m_right) && qAbs(dx) < 10)
            return;
        if ((m_top || m_bottom) && qAbs(dy) < 15)
            return;
        if (m_left && dx > 0 && mFrameRect.width() <= m_frame->minimumWidth())
            return ;
        if (m_top && dy > 0 && mFrameRect.height() <= m_frame->minimumHeight())
            return;

        QRect rc = mFrameRect;
        if (m_left){
            rc.setLeft(rc.left() + dx);
            rtMainWindow.setLeft(rtMainWindow.left() + dx);
        }
        if (m_right){
            rc.setRight(rc.right() + dx);
            rtCentralGeo.setRight(rtCentralGeo.right() + dx);
            rtMainWindow.setRight(rtMainWindow.right() + dx);
        }
        if (m_top){
            rc.setTop(rc.top() + dy);
            rtCentralGeo.setTop(rtCentralGeo.top() + dy);
            rtMainWindow.setTop(rtMainWindow.top() + dy);
        }
        if (m_bottom){
            rc.setBottom(rc.bottom() + dy);
            rtCentralGeo.setBottom(rtCentralGeo.bottom() + dy);
            rtMainWindow.setBottom(rtMainWindow.bottom() + dy);
        }
        m_frame->setGeometry(rc);
        m_frame->show();
        mFrameRect = rc;
        m_CentralRect = rtCentralGeo;
        m_pos = ev->globalPos();
    }
    else
    {
        int x = ev->x();
        int y = ev->y();

        QRect rc = m_frame->rect();
        m_left = qAbs(x - rc.left()) <= 10;
        m_right = qAbs(x - rc.right()) <= 10;
        m_top = qAbs(y - rc.top()) <= 10;
        m_bottom = qAbs(y - rc.bottom()) <= 10;

        if ((m_left && m_top) || (m_right && m_bottom))
            m_frame->setCursor(Qt::SizeFDiagCursor);
        else if ((m_right && m_top) || (m_left && m_bottom))
            m_frame->setCursor(Qt::SizeBDiagCursor);
        else if ((m_left && !m_top && !m_bottom) || (m_right && !m_top && !m_bottom))
            m_frame->setCursor(Qt::SizeHorCursor);
        else if ((m_top && !m_right && !m_left) || (m_bottom && !m_right && !m_left))
            m_frame->setCursor(Qt::SizeVerCursor);
        else
            m_frame->setCursor(Qt::ArrowCursor);
    }
}

void QssMainWindow::onMousePressEvent( QMouseEvent * ev )
{
    m_pos = ev->globalPos();
    this->show();
    mFrameRect = m_frame->geometry();
    if(nullptr != centralWidget()){
        m_CentralRect = centralWidget()->geometry();
    }
    m_mousePressedInBoundy = (ev->button() == Qt::LeftButton) && (m_left || m_right || m_top || m_bottom);

    m_iCalCursorPos = CalCursorPos(ev->pos(),CalCursorCol(ev->pos()));
    if (ev->button() == Qt::LeftButton)
    {
        if(m_iCalCursorPos != CENTER)
        {
            m_bLeftPress = true;
            m_ptViewMousePos = ev->globalPos();
            setCursor(Qt::ArrowCursor);
        }
    }
    m_rtPreGeometry = mFrameRect;

}

void QssMainWindow::onMouseReleaseEvent( QMouseEvent * ev )
{
    m_bLeftPress = false;
    m_mousePressedInBoundy = false;
}



void QssMainWindow::dpiScaleChildren()
{

}

void QssMainWindow::detectDpi()
{
    int logicdpi = logicalDpiX();
    m_dpi_ratio = this->logicalDpiX() / 96.0;

}

void QssMainWindow::rangeObjectList(QObject *obj, int indent)
{
    QObjectList child = obj->children();
    QString tmp("");
    for(int i = 0;i < indent;i++)
        tmp +=" ";

    for(int i = 0;i < child.size();i++){
       qDebug()<<tmp + child.at(i)->objectName() + " " +
                 child.at(i)->metaObject()->className();


       if(child.at(i)->metaObject()->className() =="QssTtitleBar"){
           QssTtitleBar *p = dynamic_cast<QssTtitleBar*>(child.at(i));
           if(nullptr != p){
               p->setMinimumSize(p->width()*m_dpi_ratio,
                                p->height()*m_dpi_ratio);
           }
       }

       if(child.at(i)->metaObject()->className() =="QMenuBar"){
           QMenuBar *p = dynamic_cast<QMenuBar*>(child.at(i));
           if(nullptr != p){
               p->setMinimumSize(p->width()*m_dpi_ratio,
                                p->height()*m_dpi_ratio);
           }
            continue;

       }
       if(child.at(i)->metaObject()->className() =="QDateTimeEdit"){
           QDateTimeEdit *p = dynamic_cast<QDateTimeEdit*>(child.at(i));
           if(nullptr != p){
               p->setMinimumSize(p->minimumHeight()*m_dpi_ratio,
                                p->minimumHeight()*m_dpi_ratio);
           }
           continue;
       }
       if(strcmp(child.at(i)->metaObject()->className(),"QLabel") == 0){
           QLabel *p = dynamic_cast<QLabel*>(child.at(i));
           if(nullptr != p){
               qDebug()<< "parent is "
                       << p->parent()->metaObject()->className();

                if(p->parent() != nullptr){
                    QWidget *wparent = dynamic_cast<QWidget*> (p->parent());
                    if(nullptr != wparent){
                        if(nullptr != wparent->layout()){
                            qDebug()<< "index of label in layout is "
                                    <<wparent->layout()->indexOf(p);
                        }
                    }
                }
                QFont pf = p->font();
                pf.setPointSize(pf.pointSize()*this->m_dpi_ratio);
                p->setFont(pf);
                p->setMinimumSize(p->minimumHeight()*m_dpi_ratio,
                                 p->minimumHeight()*m_dpi_ratio);
           }

           continue;
       }
       if(strcmp(child.at(i)->metaObject()->className(),"QComboBox") == 0){
           QComboBox *p = dynamic_cast<QComboBox*>(child.at(i));
           p->setMinimumSize(p->width()*m_dpi_ratio,
                            p->height()*m_dpi_ratio);
           continue;
       }

       if(strcmp(child.at(i)->metaObject()->className(),"QPushButton") == 0){

           QPushButton *p = dynamic_cast<QPushButton*>(child.at(i));
           qDebug()<<tmp + child.at(i)->objectName() + " " +
                     child.at(i)->metaObject()->className() << p->size();
           if(nullptr != p){
               p->setFixedHeight(p->height()*m_dpi_ratio);
               p->setMinimumWidth(p->width()*m_dpi_ratio);

           }
           continue;
       }

       if(strcmp(child.at(i)->metaObject()->className(),"QLineEdit") == 0){
           QLineEdit *p = dynamic_cast<QLineEdit*>(child.at(i));
           if(nullptr != p){
                p->setFixedHeight(p->height()*this->m_dpi_ratio);
                QFont pf = p->font();
           }
           continue;
       }

       if(child.at(i)->children().size() > 0){
            this->rangeObjectList(child.at(i),indent + 1);
       }
    }
}

void QssMainWindow::showEvent(QShowEvent *ev)
{

}

bool QssMainWindow::eventFilter(QObject * obj, QEvent * ev){
    if (obj == m_frame)
    {
        if (ev->type() == QEvent::Paint){

        }
        if (ev->type() == QEvent::MouseMove)
        {
            QMouseEvent * mouseEv = dynamic_cast<QMouseEvent *>(ev);
            if (ev)
            {
                onMouseMoveEvent(mouseEv);
                return false;
            }
        }
        else if (ev->type() == QEvent::MouseButtonPress)
        {
            QMouseEvent * mouseEv = dynamic_cast<QMouseEvent *>(ev);
            if (ev)
            {
                onMousePressEvent(mouseEv);
                return false;
            }
        }
        else if (ev->type() == QEvent::MouseButtonRelease)
        {
            setCursor(Qt::ArrowCursor);

            QMouseEvent * mouseEv = dynamic_cast<QMouseEvent *>(ev);
            if (ev)
            {
                onMouseReleaseEvent(mouseEv);
                return false;
            }
        }
        else if (ev->type() == QEvent::Show)
        {
            QRect rc = m_frame->rect();
            QRect parentRc = m_rcValid;

            /** m_frame */
            int x = parentRc.left() + (parentRc.width() - rc.width())*0.5; x = x <= 0 ? 1 : x;
            int y = parentRc.top() + (parentRc.height() - rc.height())*0.5; y = y <= 0 ? 1 : y;
            m_frame->move(x, y);
        }
        else if (ev->type() == QEvent::Close)
        {
            close();
            m_titleBar->close();

            return false;
        }
    }
    else if (obj == m_titleBar)
    {
        if (ev->type() == QEvent::Enter)
        {
            m_left = false;
            m_right = false;
            m_top = false;
            m_bottom = false;
            if (m_frame->cursor().shape() != Qt::ArrowCursor)
                m_frame->setCursor(Qt::ArrowCursor);
        }
        if(ev->type() == QEvent::Resize){

        }
    }
    else if (obj == this)
    {
        if (ev->type() == QEvent::Enter)
        {
            m_left = false;m_right = false; m_top = false; m_bottom = false;
            if (m_frame->cursor().shape() != Qt::ArrowCursor)
                m_frame->setCursor(Qt::ArrowCursor);
        }
        if(QEvent::Resize == ev->type()){

        }
        else if (ev->type() == QEvent::MouseButtonRelease)
        {
            setCursor(Qt::ArrowCursor);
            QMouseEvent * mouseEv = dynamic_cast<QMouseEvent *>(ev);
            if (ev)
            {
                onMouseReleaseEvent(mouseEv);
                return false;
            }
        }
        if(QEvent::Resize == ev->type()){

        }
    }
    if(QEvent::Resize == ev->type()){
        QDesktopWidget desktop;
    }
    return false;
}



void QssMainWindow::ScaleChanged(float scale)
{

}

WId QssMainWindow::GetWID() const
{
    return 0;

}

void QssMainWindow::SetScale(float scale)
{

}

void QssMainWindow::paintEvent(QPaintEvent *event)
{
    QWidget::paintEvent(event);
}

QssDialog::QssDialog(QWidget *parent)
    : QDialog(0),
    m_parent(parent),
    m_mousePressedInBorder(false)
{
    m_rcValid = QApplication::desktop()->availableGeometry();

    m_frame = new QFrame(parent);
    m_frame->setObjectName("dialog");//css
    m_frame->setAttribute(Qt::WA_TranslucentBackground);
    m_frame->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint| Qt::WindowSystemMenuHint/* | Qt::WindowMinimizeButtonHint*/);//Qt::WindowMinimizeButtonHintdialog
    m_frame->setMouseTracking(true);
    m_frame->installEventFilter(this);

    m_titleBar = new QssTtitleBar(m_frame, QssTtitleBar::QTitleBar_Type_Dialog);
    m_titleBar->installEventFilter(this);

    QVBoxLayout* vbox = new QVBoxLayout(m_frame);
    vbox->setMargin(0);
    vbox->setSpacing(0);
    vbox->addWidget(m_titleBar);
    vbox->addWidget(this);

    installEventFilter(this);

    mShadowMask = new  QWidget(this);
    mShadowMask->setStyleSheet("QWidget{background-color:rgba(1,1,1,0.3);}");
    mShadowMask->hide();
}

QssDialog::~QssDialog()
{
    m_frame->deleteLater();
}

void QssDialog::ShowMask()
{
    mShadowMask->setGeometry(0, 0, this->width(),this->height());    //遮罩窗口位置
    mShadowMask->show();
}

void QssDialog::HideMask()
{
    mShadowMask->hide();
}

void QssDialog::show()
{
    /** resize m_framem_framesizehint */
    int offset = (QSSDIALOG_SHADOW_WIDTH + QSSDIALOG_BODER_WIDTH)*2;
    m_frame->resize(rect().width() + offset, rect().height() + m_titleBar->rect().height() + offset);

    QDialog::show();
    m_frame->show();
}

void QssDockWidget::paintEvent(QPaintEvent *){
    QStyleOption opt;
    opt.init(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

void QssDockWidget::show()
{
    int offset = (QSSDIALOG_SHADOW_WIDTH + QSSDIALOG_BODER_WIDTH)*2;//rect()����padding��paddingframe
    m_frame->resize(rect().width() + offset, rect().height() + m_titleBar->rect().height() + offset);

    QDockWidget::show();
    m_frame->show();
}

void QssDialog::raise()
{
    m_frame->raise();
}

void QssDialog::activateWindow()
{
    m_frame->activateWindow();
}

int QssDialog::exec()
{
    /** resize m_framem_framesizehint */
    int offset = (QSSDIALOG_SHADOW_WIDTH + QSSDIALOG_BODER_WIDTH)*2;//rect()����padding��paddingframe
    m_frame->resize(rect().width() + offset, rect().height() + m_titleBar->rect().height() + offset);

    m_frame->setWindowModality(Qt::ApplicationModal);//Qt::ApplicationModal

    m_frame->show();
    m_frame->raise();
    m_frame->activateWindow();

    int ret = QDialog::exec();
    m_frame->close();

    return ret;
}

void QssDialog::setWindowTitle( QString title )
{
    m_frame->setWindowTitle(title);
    m_titleBar->setTitle(title);
}

void QssDialog::setWindowIcon( QIcon icon )
{
    m_frame->setWindowIcon(icon);
    m_titleBar->setIcon(icon);
}

void QssDialog::onMouseMoveEvent( QMouseEvent * ev )
{
    if (m_mousePressedInBorder) {
        int x = ev->globalPos().x();
        int y = ev->globalPos().y();

        int dx = x - m_pos.x();
        int dy = y - m_pos.y();

        if ((m_left || m_right) && qAbs(dx) < 5)
            return;
        if ((m_top || m_bottom) && qAbs(dy) < 5)
            return;
        if (m_left && dx > 0 && mFrameRect.width() <= m_frame->minimumWidth())
            return ;
        if (m_top && dy > 0 && mFrameRect.height() <= m_frame->minimumHeight())
            return;

        QRect rc = mFrameRect;
        if (m_left)
            rc.setLeft(rc.left() + dx);
        if (m_right)
            rc.setRight(rc.right() + dx);
        if (m_top)
            rc.setTop(rc.top() + dy);
        if (m_bottom)
            rc.setBottom(rc.bottom() + dy);
        qDebug()<<"onMouseMoveEvent"<<rc;
        m_frame->setGeometry(rc);
        mFrameRect = rc;
        m_pos = ev->globalPos();
    }
    else {
        int x = ev->x() + QSSDIALOG_SHADOW_WIDTH - 2;
        int y = ev->y() + QSSDIALOG_SHADOW_WIDTH - 2;

        QRect rc = m_frame->rect();
        m_left = qAbs(x - rc.left()) <= 5;
        m_right = qAbs(x - rc.right()) <= 5;
        m_top = qAbs(y - rc.top()) <= 5;
        m_bottom = qAbs(y - rc.bottom()) <= 5;

        if ((m_left && m_top) || (m_right && m_bottom))
            m_frame->setCursor(Qt::SizeFDiagCursor);
        else if ((m_right && m_top) || (m_left && m_bottom))
            m_frame->setCursor(Qt::SizeBDiagCursor);
        else if ((m_left && !m_top && !m_bottom) || (m_right && !m_top && !m_bottom))
            m_frame->setCursor(Qt::SizeHorCursor);
        else if ((m_top && !m_right && !m_left) || (m_bottom && !m_right && !m_left))
            m_frame->setCursor(Qt::SizeVerCursor);
        else
            m_frame->setCursor(Qt::ArrowCursor);
    }
}

void QssDockWidget::onMouseMoveEvent( QMouseEvent * ev )
{
    if (m_mousePressedInBorder)
    {
        int x = ev->globalPos().x();
        int y = ev->globalPos().y();

        int dx = x - m_pos.x();
        int dy = y - m_pos.y();

        if ((m_left || m_right) && qAbs(dx) < 5)
            return;
        if ((m_top || m_bottom) && qAbs(dy) < 5)
            return;
        if (m_left && dx > 0 && mFrameRect.width() <= m_frame->minimumWidth())
            return ;
        if (m_top && dy > 0 && mFrameRect.height() <= m_frame->minimumHeight())
            return;

        QRect rc = mFrameRect;
        if (m_left)
            rc.setLeft(rc.left() + dx);
        if (m_right)
            rc.setRight(rc.right() + dx);
        if (m_top)
            rc.setTop(rc.top() + dy);
        if (m_bottom)
            rc.setBottom(rc.bottom() + dy);

        m_frame->setGeometry(rc);
        mFrameRect = rc;
        m_pos = ev->globalPos();
    }
    else
    {
        int x = ev->x() + QSSDIALOG_SHADOW_WIDTH - 2;
        int y = ev->y() + QSSDIALOG_SHADOW_WIDTH - 2;

        QRect rc = m_frame->rect();
        m_left = qAbs(x - rc.left()) <= 5;
        m_right = qAbs(x - rc.right()) <= 5;
        m_top = qAbs(y - rc.top()) <= 5;
        m_bottom = qAbs(y - rc.bottom()) <= 5;

        if ((m_left && m_top) || (m_right && m_bottom))
            m_frame->setCursor(Qt::SizeFDiagCursor);
        else if ((m_right && m_top) || (m_left && m_bottom))
            m_frame->setCursor(Qt::SizeBDiagCursor);
        else if ((m_left && !m_top && !m_bottom) || (m_right && !m_top && !m_bottom))
            m_frame->setCursor(Qt::SizeHorCursor);
        else if ((m_top && !m_right && !m_left) || (m_bottom && !m_right && !m_left))
            m_frame->setCursor(Qt::SizeVerCursor);
        else
            m_frame->setCursor(Qt::ArrowCursor);
    }
}

void QssDialog::onMousePressEvent( QMouseEvent * ev )
{
    m_pos = ev->globalPos();
    mFrameRect = m_frame->geometry();
    if(m_left || m_right || m_top || m_bottom)
    {
        m_mousePressedInBorder = ev->button() == Qt::LeftButton;
        //qDebug() << "mousePressed pressed in border";
    }
}


void QssDockWidget::onMousePressEvent( QMouseEvent * ev )
{
    m_pos = ev->globalPos();
    mFrameRect = m_frame->geometry();
    if(m_left || m_right || m_top || m_bottom)
    {
        m_mousePressedInBorder = ev->button() == Qt::LeftButton;
        //qDebug() << "mousePressed pressed in border";
    }
}

void QssDialog::onMouseReleaseEvent( QMouseEvent *  )
{
    m_mousePressedInBorder = false;
}

void QssDockWidget::onMouseReleaseEvent( QMouseEvent * ev )
{
    ev = ev;
    m_mousePressedInBorder = false;
}

bool QssDialog::eventFilter( QObject * obj, QEvent * ev )
{
    if (obj == m_frame)
    {
        if (ev->type() == QEvent::MouseMove)
        {
            QMouseEvent * mouseEv = dynamic_cast<QMouseEvent *>(ev);
            if (ev)
            {
                onMouseMoveEvent(mouseEv);
                return true;
            }
        }
        else if (ev->type() == QEvent::MouseButtonPress)
        {
            QMouseEvent * mouseEv = dynamic_cast<QMouseEvent *>(ev);
            if (ev)
            {
                onMousePressEvent(mouseEv);
                return true;
            }
        }
        else if (ev->type() == QEvent::MouseButtonRelease)
        {
            QMouseEvent * mouseEv = dynamic_cast<QMouseEvent *>(ev);
            if (ev)
            {
                onMouseReleaseEvent(mouseEv);
                return true;
            }
        }/**  */
        else if (ev->type() == QEvent::Paint)
        {
            const int shadowWidth = QSSDIALOG_SHADOW_WIDTH;
            const int boderWidht = QSSDIALOG_BODER_WIDTH;

            QPainter paiter(m_frame);

            QColor colorBorder(0xaa,0xaa,0xaa);
            paiter.setPen(colorBorder);

            int boderOffset = shadowWidth + boderWidht - 1;
            paiter.drawLine(boderOffset,boderOffset,m_frame->width() - boderOffset - 1, boderOffset);//top
            paiter.drawLine(boderOffset,m_frame->height() - boderOffset - 1,m_frame->width() - boderOffset - 1, m_frame->height() - boderOffset - 1);//bottom

            paiter.drawLine(boderOffset,boderOffset,boderOffset,m_frame->height() - boderOffset - 1);//left
            paiter.drawLine(m_frame->width() - boderOffset - 1,boderOffset,m_frame->width() - boderOffset - 1,m_frame->height() - boderOffset - 1);//right

            QColor colorShadow(0xaa,0xaa,0xaa);
            for (int i = 0; i < shadowWidth; i++)
            {
                colorShadow.setAlpha(100*cos(1.5707963*i/(shadowWidth - 1)));
                paiter.setPen(colorShadow);
                paiter.drawRect(boderOffset + i, boderOffset + i,
                    m_frame->width() - 2*shadowWidth ,
                    m_frame->height() - 2*shadowWidth );
            }
        }
        else if (ev->type() == QEvent::Show)
        {
            QRect rc = m_frame->rect(), parentRc;
            if (m_parent)
            {
                /**  */
                QPoint pt = m_parent->mapToGlobal(QPoint(0,0));
                parentRc =m_parent->rect();
                parentRc.translate(pt);
            }
            else/** */
                parentRc = m_rcValid;

            /** m_frame */
            int x = parentRc.left() + (parentRc.width() - rc.width())*0.5;x = x <= 0?1:x;
            int y = parentRc.top() + (parentRc.height() - rc.height())*0.5;y = y <= 0?1:y;
            m_frame->move(x,y);

            /**  */
            QPropertyAnimation* aniSize = new QPropertyAnimation(m_frame,"geometry");
            aniSize->setDuration(200);
            aniSize->setKeyValueAt(0, QRect(x,y,0,0));
            aniSize->setKeyValueAt(0.5, QRect(x ,y,rc.width() + 20,rc.height() + 30));
            aniSize->setKeyValueAt(1 , QRect(x,y,rc.width(),rc.height()));
            //aniSize->setEasingCurve(QEasingCurve::InOutBack);//

            QPropertyAnimation* aniOpacity = new QPropertyAnimation(m_frame,"windowOpacity");
            aniOpacity->setDuration(200);
            aniOpacity->setStartValue(0);
            aniOpacity->setEndValue(1);

            QParallelAnimationGroup* aniGroup = new QParallelAnimationGroup(m_frame);
            aniGroup->addAnimation(aniSize);
            aniGroup->addAnimation(aniOpacity);

            aniGroup->start(QAbstractAnimation::DeleteWhenStopped);

        }
        else if (ev->type() == QEvent::Close)
        {
            close();
        }
    }
    else if (obj == m_titleBar)
    {
        if (ev->type() == QEvent::Enter)
        {
            m_left = false;m_right = false; m_top = false; m_bottom = false;
            if (m_frame->cursor().shape() != Qt::ArrowCursor)
                m_frame->setCursor(Qt::ArrowCursor);
        }
    }
    else if (obj == this)
    {
        if (ev->type() == QEvent::Enter)
        {
            m_left = false;m_right = false; m_top = false; m_bottom = false;
            if (m_frame->cursor().shape() != Qt::ArrowCursor)
                m_frame->setCursor(Qt::ArrowCursor);
        }
        else if (ev->type() == QEvent::Hide)
        {
            m_frame->hide();
            return true;
        }
    }
    return QDialog::eventFilter(obj, ev);
}

QssMessageBox::QssMessageBox( Icon icon, const QString &title, const QString &text,
                              StandardButtons buttons /*= NoButton*/,
                              QWidget *parent /*= 0*/,
                              Qt::WindowFlags flags /*= Qt::Widget | Qt::FramelessWindowHint*/ )
:QMessageBox(icon, title, text, buttons, 0, flags),m_parent(parent)
{
    m_rcValid = QApplication::desktop()->availableGeometry();

    m_frame = new QFrame;
    m_frame->setObjectName("messagebox");//css
    //m_frame->setAttribute(Qt::WA_TranslucentBackground);/** padding */
    m_frame->setWindowFlags(Qt::FramelessWindowHint);
    m_frame->setMouseTracking(true);
    m_frame->installEventFilter(this);

    m_frame->setWindowTitle(title);
    m_frame->setWindowIcon(style()->standardIcon((QStyle::StandardPixmap)(icon + 8)));
    m_frame->setWindowModality(Qt::ApplicationModal);

    m_titleBar = new QssTtitleBar(m_frame, QssTtitleBar::QTitleBar_Type_MessageBox);
    m_titleBar->installEventFilter(this);

    m_titleBar->setTitle(title);
    m_titleBar->setIcon(style()->standardIcon((QStyle::StandardPixmap)(icon + 8)));

    QVBoxLayout* vbox = new QVBoxLayout(m_frame);
    vbox->setMargin(0);
    vbox->setSpacing(0);
    vbox->addWidget(m_titleBar);
    vbox->addWidget(this);

    installEventFilter(this);
}

QssMessageBox::QssMessageBox( QWidget *parent /*= 0*/ )
:QMessageBox(parent),m_parent(parent)
{
    m_rcValid = QApplication::desktop()->availableGeometry();

    m_frame = new QFrame;
    m_frame->setObjectName("messagebox");//css
    m_frame->setAttribute(Qt::WA_TranslucentBackground);/** padding */
    m_frame->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint);
    m_frame->setMouseTracking(true);
    m_frame->installEventFilter(this);
    m_frame->setWindowModality(Qt::ApplicationModal);
    m_titleBar = new QssTtitleBar(m_frame, QssTtitleBar::QTitleBar_Type_MessageBox);
    m_titleBar->installEventFilter(this);

    QVBoxLayout* vbox = new QVBoxLayout(m_frame);
    vbox->setMargin(0);
    vbox->setSpacing(0);
    vbox->addWidget(m_titleBar);
    vbox->addWidget(this);
    this->setStyleSheet("{background:rgb(0,0,0);}");
    installEventFilter(this);
}

QssMessageBox::~QssMessageBox()
{
    m_frame->deleteLater();
}

bool QssMessageBox::eventFilter( QObject * obj, QEvent * ev )
{
    if (obj == m_frame)
    {
        if (ev->type() == QEvent::Paint)
        {
            const int shadowWidth = QSSDIALOG_SHADOW_WIDTH;
            const int boderWidht = QSSDIALOG_BODER_WIDTH;

            QPainter paiter(m_frame);

            QColor colorBorder(0xaa,0xaa,0xaa);
            paiter.setPen(colorBorder);

            int boderOffset = shadowWidth + boderWidht - 1;
            paiter.drawLine(boderOffset,boderOffset,m_frame->width() - boderOffset - 1, boderOffset);//top
            paiter.drawLine(boderOffset,m_frame->height() - boderOffset - 1,m_frame->width() - boderOffset - 1, m_frame->height() - boderOffset - 1);//bottom

            paiter.drawLine(boderOffset,boderOffset,boderOffset,m_frame->height() - boderOffset - 1);//left
            paiter.drawLine(m_frame->width() - boderOffset - 1,boderOffset,m_frame->width() - boderOffset - 1,m_frame->height() - boderOffset - 1);//right

            QColor colorShadow(0xaa,0xaa,0xaa);
            for (int i = 0; i < shadowWidth; i++)
            {
                colorShadow.setAlpha(100*cos(1.5707963*i/(shadowWidth - 1)));
                paiter.setPen(colorShadow);
                paiter.drawRect(boderOffset + i, boderOffset + i,
                    m_frame->width() - 2*shadowWidth ,
                    m_frame->height() - 2*shadowWidth );
            }
        }
        else if (ev->type() == QEvent::Show)
        {
            QRect rc = m_frame->rect(), parentRc;
            if (m_parent)/**�� */
            {
                QPoint pt = m_parent->mapToGlobal(QPoint(0,0));
                parentRc =m_parent->rect();
                parentRc.translate(pt);
            }
            else/** */
                parentRc = m_rcValid;
            /** m_frame */
            int x = parentRc.left() + (parentRc.width() - rc.width())*0.5;x = x <= 0?1:x;
            int y = parentRc.top() + (parentRc.height() - rc.height())*0.5;y = y <= 0?1:y;
            m_frame->move(x,y);
            /**  */
            QPropertyAnimation* aniSize = new QPropertyAnimation(m_frame,"geometry");
            aniSize->setDuration(200);
            aniSize->setKeyValueAt(0, QRect(x,y,0,0));
            aniSize->setKeyValueAt(0.5, QRect(x ,y,rc.width() + 10,rc.height() + 15));
            aniSize->setKeyValueAt(1 , QRect(x,y,rc.width(),rc.height()));
            //aniSize->setEasingCurve(QEasingCurve::InOutBack);//

            QPropertyAnimation* aniOpacity = new QPropertyAnimation(m_frame,"windowOpacity");
            aniOpacity->setDuration(200);
            aniOpacity->setStartValue(0);
            aniOpacity->setEndValue(1);

            QParallelAnimationGroup* aniGroup = new QParallelAnimationGroup(m_frame);
            aniGroup->addAnimation(aniSize);
            aniGroup->addAnimation(aniOpacity);

            aniGroup->start(QAbstractAnimation::DeleteWhenStopped);

        }
        else if (ev->type() == QEvent::Close)
        {
            close();
            m_titleBar->close();
        }
    }
    else if(obj == this)
    {
        if (ev->type() == QEvent::Resize)
        {
            frame()->setFixedWidth(size().width());
        }
    }

    return QDialog::eventFilter(obj, ev);
}

QMessageBox::StandardButton QssMessageBox::tips( const QString & text, QWidget* parent /*= 0*/, const QString & title /*= QString::fromLocal8Bit("")*/, StandardButtons btn /*= QMessageBox::Ok*/ )
{
    QssMessageBox box(QMessageBox::Information, title, "\n" + text/* + "\n"*/, btn, parent);
    box.setDefaultButton(QMessageBox::Ok);

    box.frame()->show();
    box.frame()->raise();
    box.frame()->activateWindow();

    QMessageBox::StandardButton ret = (QMessageBox::StandardButton)box.exec();
    box.frame()->close();

    return ret;
}

QMessageBox::StandardButton QssMessageBox::warn( const QString & text, QWidget* parent /*= 0*/, const QString & title /*= QString::fromLocal8Bit("")*/, StandardButtons btn /*= QMessageBox::Ok*/ )
{
    QssMessageBox box(QMessageBox::Warning, title, "\n" + text/* + "\n"*/ , btn, parent);
    box.setDefaultButton(QMessageBox::Ok);

    box.frame()->show();
    box.frame()->raise();
    box.frame()->activateWindow();

    QMessageBox::StandardButton ret = (QMessageBox::StandardButton)box.exec();
    box.frame()->close();

    return ret;
}

QMessageBox::StandardButton QssMessageBox::error( const QString & text, QWidget* parent /*= 0*/, const QString & title /*= QString::fromLocal8Bit("")*/, StandardButtons btn /*= QMessageBox::Ok*/ )
{
    QssMessageBox box(QMessageBox::Critical, title, "\n" + text/* + "\n"*/, btn, parent);
    box.setDefaultButton(QMessageBox::Ok);

    box.frame()->show();
    box.frame()->raise();
    box.frame()->activateWindow();

    QMessageBox::StandardButton ret = (QMessageBox::StandardButton)box.exec();
    box.frame()->close();

    return ret;
}

QMessageBox::StandardButton QssMessageBox::ask( const QString & text, QWidget* parent /*= 0*/, const QString & title /*= QString::fromLocal8Bit("")*/, StandardButtons btn /*= QMessageBox::Yes | QMessageBox::No*/ )
{
    QssMessageBox box(QMessageBox::Question, title, "\n" + text/* + "\n"*/, btn, parent);
    box.setDefaultButton(QMessageBox::Yes);

    box.frame()->show();
    box.frame()->raise();
    box.frame()->activateWindow();

    QMessageBox::StandardButton ret = (QMessageBox::StandardButton)box.exec();
    box.frame()->close();

    return ret;
}


QMessageBox::StandardButton QssMessageBox::regard( const QString & text, QWidget* parent /*= 0*/, const QString & title /*= QString::fromLocal8Bit("")*/ )
{
    QssMessageBox box(parent);

    QIcon icon = QApplication::windowIcon();
    QSize size = icon.actualSize(QSize(64, 64));
    box.setIconPixmap(icon.pixmap(size));
    box.setDefaultButton(QMessageBox::Ok);

    box.frame()->setWindowIcon(icon);
    box.titleBar()->setIcon(icon);

    box.frame()->setWindowTitle(title);
    box.titleBar()->setTitle(title);

    box.setInformativeText(text);

    box.frame()->show();
    box.frame()->raise();
    box.frame()->activateWindow();

    QMessageBox::StandardButton ret = (QMessageBox::StandardButton)box.exec();
    box.frame()->close();

    return ret;
}

QMessageBox::StandardButton QssMessageBox::regard( const QString & text, QIcon icon, QWidget* parent /*= 0*/, const QString & title /*= QString::fromLocal8Bit("")*/ )
{
    QssMessageBox box(parent);
    QSize size = icon.actualSize(QSize(64, 64));
    box.setIconPixmap(icon.pixmap(size));
    box.setDefaultButton(QMessageBox::Ok);

    box.frame()->setWindowIcon(icon);
    box.titleBar()->setIcon(icon);

    box.frame()->setWindowTitle(title);
    box.titleBar()->setTitle(title);

    box.setInformativeText(text);

    box.frame()->show();
    box.frame()->raise();
    box.frame()->activateWindow();

    QMessageBox::StandardButton ret = (QMessageBox::StandardButton)box.exec();
    box.frame()->close();

    return ret;
}

QMessageBox::StandardButton QssMessageBox::regardQt(QWidget* parent /*= 0*/, const QString & title /*= QString::fromLocal8Bit("Qt")*/ )
{
    QString translatedTextAboutQtCaption;
    translatedTextAboutQtCaption = QMessageBox::tr(
        "<h3>About Qt</h3>"
        "<p>This program uses Qt version %1.</p>"
        ).arg(QLatin1String(QT_VERSION_STR));
    QString translatedTextAboutQtText;
    translatedTextAboutQtText = QMessageBox::tr(
        "<p>Qt is a C++ toolkit for cross-platform application "
        "development.</p>"
        "<p>Qt provides single-source portability across MS&nbsp;Windows, "
        "Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. "
        "Qt is also available for embedded devices as Qt for Embedded Linux "
        "and Qt for Windows CE.</p>"
        "<p>Qt is available under three different licensing options designed "
        "to accommodate the needs of our various users.</p>"
        "<p>Qt licensed under our commercial license agreement is appropriate "
        "for development of proprietary/commercial software where you do not "
        "want to share any source code with third parties or otherwise cannot "
        "comply with the terms of the GNU LGPL version 2.1 or GNU GPL version "
        "3.0.</p>"
        "<p>Qt licensed under the GNU LGPL version 2.1 is appropriate for the "
        "development of Qt applications (proprietary or open source) provided "
        "you can comply with the terms and conditions of the GNU LGPL version "
        "2.1.</p>"
        "<p>Qt licensed under the GNU General Public License version 3.0 is "
        "appropriate for the development of Qt applications where you wish to "
        "use such applications in combination with software subject to the "
        "terms of the GNU GPL version 3.0 or where you are otherwise willing "
        "to comply with the terms of the GNU GPL version 3.0.</p>"
        "<p>Please see <a href=\"http://qt.nokia.com/products/licensing\">qt.nokia.com/products/licensing</a> "
        "for an overview of Qt licensing.</p>"
        "<p>Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).</p>"
        "<p>Qt is a Nokia product. See <a href=\"http://qt.nokia.com/\">qt.nokia.com</a> "
        "for more information.</p>"
        );

    QPixmap pm(QMessageBox::tr(":/trolltech/qmessagebox/images/qtlogo-64.png"));

    QssMessageBox box(parent);
    box.setWindowTitle(title.isEmpty() ? QString::fromLocal8Bit("Qt") : title);
    box.setText(translatedTextAboutQtCaption);
    box.setInformativeText(translatedTextAboutQtText);
    if (!pm.isNull())
        box.setIconPixmap(pm);
    box.setDefaultButton(QMessageBox::Ok);

    box.frame()->setWindowIcon(QIcon(":/trolltech/qmessagebox/images/qtlogo-64.png"));
    box.frame()->setWindowTitle(title.isEmpty() ? QString::fromLocal8Bit("Qt") : title);
    box.titleBar()->setIcon(QIcon(":/trolltech/qmessagebox/images/qtlogo-64.png"));
    box.titleBar()->setTitle(title.isEmpty() ? QString::fromLocal8Bit("Qt") : title);

    box.frame()->show();
    box.frame()->raise();
    box.frame()->activateWindow();

    QMessageBox::StandardButton ret = (QMessageBox::StandardButton)box.exec();
    box.frame()->close();

    return ret;
}


QMessageBox::StandardButton QssMessageBox::information( QWidget *parent, const QString &title, const QString &text, StandardButtons buttons /*= Ok*/, StandardButton defaultButton /*= NoButton*/ )
{
    return QssMessageBox::tips(text, parent, title, buttons);
}

QMessageBox::StandardButton QssMessageBox::question( QWidget *parent, const QString &title, const QString &text, StandardButtons buttons /*= QMessageBox::Ok*/, StandardButton defaultButton /*= QMessageBox::NoButton*/ )
{
    return QssMessageBox::ask(text, parent, title, buttons);
}

QMessageBox::StandardButton QssMessageBox::warning( QWidget *parent, const QString &title, const QString &text, StandardButtons buttons /*= QMessageBox::Ok*/, StandardButton defaultButton /*= QMessageBox::NoButton*/ )
{
    return QssMessageBox::warn(text, parent, title, buttons);
}

QMessageBox::StandardButton QssMessageBox::critical( QWidget *parent, const QString &title, const QString &text, StandardButtons buttons /*= QMessageBox::Ok*/, StandardButton defaultButton /*= QMessageBox::NoButton*/ )
{
    return QssMessageBox::error(text, parent, title, buttons);
}

void QssMessageBox::about( QWidget *parent, const QString &title, const QString &text )
{
    QssMessageBox::regard(text, parent, title);
}

void QssMessageBox::about( QWidget *parent, const QString &title, const QString &text, QIcon icon )
{
    QssMessageBox::regard(text, icon, parent, title);
}

void QssMessageBox::aboutQt( QWidget *parent, const QString &title /*= QString()*/ )
{
    QssMessageBox::regardQt(parent, title);
}


QssDockWidget::QssDockWidget(QWidget *parent)
    : QDockWidget(parent),
      m_parent(parent),
    m_mousePressedInBorder(false)
{
    m_rcValid = QApplication::desktop()->availableGeometry();

    m_frame = new QFrame(parent);
    m_frame->setObjectName("dialog");//css
    m_frame->setAttribute(Qt::WA_TranslucentBackground);/** padding css boder��*/
    m_frame->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
    m_frame->setMouseTracking(true);
    m_frame->installEventFilter(this);

    m_titleBar = new QssTtitleBar(m_frame, QssTtitleBar::QTitleBar_Type_Dialog);
    m_titleBar->installEventFilter(this);

    QVBoxLayout* vbox = new QVBoxLayout(m_frame);
    vbox->setMargin(0);
    vbox->setSpacing(0);
    vbox->addWidget(m_titleBar);
    vbox->addWidget(this);

    installEventFilter(this);
    this->setStyleSheet(QString("{background: rgb(232, 241, 252);""color: black;border: 1px solid rgb(111, 156, 207);}"));


    mShadowMask = new  QWidget(this);
    mShadowMask->setStyleSheet("QWidget{background-color:rgba(1,1,1,0.3);}");
    mShadowMask->hide();
}

void QssDockWidget::ShowMask()
{
    mShadowMask->setGeometry(0, 0, this->width(),this->height());    //遮罩窗口位置
    mShadowMask->show();
}

void QssDockWidget::HideMask()
{
    mShadowMask->hide();
}

QssDockWidget::~QssDockWidget()
{
    m_frame->deleteLater();
}

void QssDockWidget::setWindowTitle(QString title)
{
    m_frame->setWindowTitle(title);
    m_titleBar->setTitle(title);
}

bool QssDockWidget::eventFilter(QObject *obj, QEvent *ev)
{
    if (obj == m_frame)
    {
        if (ev->type() == QEvent::MouseMove)
        {
            QMouseEvent * mouseEv = dynamic_cast<QMouseEvent *>(ev);
            if (ev)
            {
                onMouseMoveEvent(mouseEv);
                return true;
            }
        }
        else if (ev->type() == QEvent::MouseButtonPress)
        {
            QMouseEvent * mouseEv = dynamic_cast<QMouseEvent *>(ev);
            if (ev)
            {
                onMousePressEvent(mouseEv);
                return true;
            }
        }
        else if (ev->type() == QEvent::MouseButtonRelease)
        {
            QMouseEvent * mouseEv = dynamic_cast<QMouseEvent *>(ev);
            if (ev)
            {
                onMouseReleaseEvent(mouseEv);
                return true;
            }
        }/**  */
        else if (ev->type() == QEvent::Paint)
        {
            const int shadowWidth = QSSDIALOG_SHADOW_WIDTH;
            const int boderWidht = QSSDIALOG_BODER_WIDTH;

            QPainter paiter(m_frame);

            QColor colorBorder(0xaa,0xaa,0xaa);
            paiter.setPen(colorBorder);

            int boderOffset = shadowWidth + boderWidht - 1;
            paiter.drawLine(boderOffset,boderOffset,m_frame->width() - boderOffset - 1, boderOffset);//top
            paiter.drawLine(boderOffset,m_frame->height() - boderOffset - 1,m_frame->width() - boderOffset - 1, m_frame->height() - boderOffset - 1);//bottom

            paiter.drawLine(boderOffset,boderOffset,boderOffset,m_frame->height() - boderOffset - 1);//left
            paiter.drawLine(m_frame->width() - boderOffset - 1,boderOffset,m_frame->width() - boderOffset - 1,m_frame->height() - boderOffset - 1);//right

            QColor colorShadow(0xaa,0xaa,0xaa);
            for (int i = 0; i < shadowWidth; i++)
            {
                colorShadow.setAlpha(100*cos(1.5707963*i/(shadowWidth - 1)));
                paiter.setPen(colorShadow);
                paiter.drawRect(boderOffset + i, boderOffset + i,
                    m_frame->width() - 2*shadowWidth ,
                    m_frame->height() - 2*shadowWidth );
            }
        }
        else if (ev->type() == QEvent::Show)
        {
            QRect rc = m_frame->rect(), parentRc;
            if (m_parent)
            {

                QPoint pt = m_parent->mapToGlobal(QPoint(0,0));
                parentRc =m_parent->rect();
                parentRc.translate(pt);
            }
            else
                parentRc = m_rcValid;

            int x = parentRc.left() + (parentRc.width() - rc.width())*0.5;x = x <= 0?1:x;
            int y = parentRc.top() + (parentRc.height() - rc.height())*0.5;y = y <= 0?1:y;
            m_frame->move(x,y);

            QPropertyAnimation* aniSize = new QPropertyAnimation(m_frame,"geometry");
            aniSize->setDuration(200);
            aniSize->setKeyValueAt(0, QRect(x,y,0,0));
            aniSize->setKeyValueAt(0.5, QRect(x ,y,rc.width() + 20,rc.height() + 30));
            aniSize->setKeyValueAt(1 , QRect(x,y,rc.width(),rc.height()));
            //aniSize->setEasingCurve(QEasingCurve::InOutBack);//

            QPropertyAnimation* aniOpacity = new QPropertyAnimation(m_frame,"windowOpacity");
            aniOpacity->setDuration(200);
            aniOpacity->setStartValue(0);
            aniOpacity->setEndValue(1);

            QParallelAnimationGroup* aniGroup = new QParallelAnimationGroup(m_frame);
            aniGroup->addAnimation(aniSize);
            aniGroup->addAnimation(aniOpacity);

            aniGroup->start(QAbstractAnimation::DeleteWhenStopped);
        }
        else if (ev->type() == QEvent::Close)
        {
            close();
        }
    }
    else if (obj == m_titleBar)
    {
        if (ev->type() == QEvent::Enter)
        {
            m_left = false;m_right = false; m_top = false; m_bottom = false;
            if (m_frame->cursor().shape() != Qt::ArrowCursor)
                m_frame->setCursor(Qt::ArrowCursor);
        }
    }
    else if (obj == this)
    {
        if (ev->type() == QEvent::Enter)
        {
            m_left = false;m_right = false; m_top = false; m_bottom = false;
            if (m_frame->cursor().shape() != Qt::ArrowCursor)
                m_frame->setCursor(Qt::ArrowCursor);
        }
        else if (ev->type() == QEvent::Hide)
        {
            m_frame->hide();
            return true;
        }
    }

    return QDockWidget::eventFilter(obj, ev);
}

QssPushButton::QssPushButton(QWidget *parent, QString objName):
    QPushButton(parent)
{
    this->setObjectName(objName);

}


QssToastWidget::QssToastWidget(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);

    setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::Tool);// 无边框 无任务栏
    setAttribute(Qt::WA_TranslucentBackground, true);   // 背景透明
}

QssToastWidget::~QssToastWidget()
{
}
void QssToastWidget::setText(const QString& text)
{
    ui.label->setText(text);
}

void QssToastWidget::showAnimation(int timeout /*= 2000*/)
{
    // 开始动画
    QPropertyAnimation *animation = new QPropertyAnimation(this, "windowOpacity");
    animation->setDuration(1000);
    animation->setStartValue(0);
    animation->setEndValue(1);
    animation->start();
    show();

    QTimer::singleShot(timeout, [&]
    {
        // 结束动画
        QPropertyAnimation *animation = new QPropertyAnimation(this, "windowOpacity");
        animation->setDuration(1000);
        animation->setStartValue(1);
        animation->setEndValue(0);
        animation->start();
        connect(animation, &QPropertyAnimation::finished, [&]
        {
            close();
            deleteLater();// 关闭后析构
        });
    });
}

void QssToastWidget::showTip(const QString& text, QWidget* parent /*= nullptr*/)
{
    QssToastWidget* toast = new QssToastWidget(parent);
    toast->setWindowFlags(toast->windowFlags() | Qt::WindowStaysOnTopHint);
    toast->setText(text);
    toast->setStyleSheet("font:bold;font-size:10px;color:rgb(255,255,255);");
    toast->adjustSize();
    qDebug()<<parent->geometry();
    QScreen* pScreen = QGuiApplication::primaryScreen();
    toast->move((pScreen->size().width() - toast->width()) / 2,
                pScreen->size().height() * 5 / 10);
    toast->showAnimation(1000);
}

void QssToastWidget::paintEvent(QPaintEvent *event)
{
    QPainter paint(this);
    paint.begin(this);
    auto kBackgroundColor = QColor(255, 255, 255);
    kBackgroundColor.setAlpha(0.0 * 255);// 透明度为0
    paint.setRenderHint(QPainter::Antialiasing, true);
    paint.setPen(Qt::NoPen);
    paint.setBrush(QBrush(kBackgroundColor, Qt::SolidPattern));//设置画刷形式
    paint.drawRect(0, 0, width(), height());
    paint.end();
}


QSSProcessBar::QSSProcessBar(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Process)
{
    qDebug()<<"Qt::WindowCloseButtonHint: "<< ~int(Qt::WindowCloseButtonHint);
    ui->setupUi(this);
    ui->progressBar->setValue(1);

    setWindowFlags(this->windowFlags()
                   & (~Qt::WindowCloseButtonHint)
                   & (~Qt::WindowContextHelpButtonHint));
    mParent = parent;
    this->hide();
    this->setModal(true);
}

QSSProcessBar::~QSSProcessBar()
{
    delete ui;
}

void QSSProcessBar::showEvent(QShowEvent *ev)
{
    ui->progressBar->setValue(0);
    if(nullptr != mParent){
        this->move(mParent->geometry().width()/2 - this->width()/2,
                   mParent->geometry().height()/2 - this->height()/2);
    }
    QDialog::showEvent(ev);
}

void QSSProcessBar::on_percent(int percent)
{
    ui->progressBar->setValue(percent);
}

void QSSProcessBar::on_done_close()
{
    this->close();
}


QssMaskWidget::QssMaskWidget(QWidget *parent)
    :mParent(nullptr)
{
    if(nullptr != parent)  {
        parent->installEventFilter(this);
        mParent = parent;
    }
    this->installEventFilter(this);

    QPalette palette = this->palette();
    palette.setBrush(QPalette::Background, QColor(0,0,0));
    this->setPalette(palette);
    this->setWindowOpacity(0.5);//设置窗口透明度
    this->setWindowFlags(Qt::FramelessWindowHint | windowFlags());//去掉标题栏

}

QssMaskWidget::~QssMaskWidget()
{

}

bool QssMaskWidget::eventFilter(QObject *obj, QEvent *ev)
{
    if(obj != this){
        if(mParent != nullptr){
            if(mParent->parentWidget() != nullptr){
                this->move(mParent->parentWidget()->geometry().width()/2,
                           mParent->parentWidget()->geometry().height()/2);
                this->show();
                this->raise();
            }
        }
    }
    if(obj == this){
        return true;
    }

    return false;
}

void QssMaskWidget::paintEvent(QPaintEvent *event)
{
    QWidget::paintEvent(event);
}

QSSASyncProcess::QSSASyncProcess(QWidget *parent)
    :mFirst(true)
{
    this->mParent = parent;
}

QSSASyncProcess::~QSSASyncProcess()
{
    this->mThread.exit(0);
    this->mThread.terminate();
}

int QSSASyncProcess::Start(void *p)
{
    this->moveToThread(&mThread);
    if(mFirst){
        connect(this, SIGNAL(StartRun(void *)), this, SLOT(Run(void *)));
        connect(&mThread, &QThread::finished, this, &QObject::deleteLater);
        mFirst = false;
    }
    mThread.start();
#ifdef QT_NO_EMIT
    StartRun(p);
#else
    emit StartRun(p);
#endif
    return 0;
}

QThread &QSSASyncProcess::Thread()
{
    return mThread;
}

void QSSASyncProcess::Run(void *)
{
#ifdef QT_NO_EMIT
    Done();
#else
    emit(Done());
#endif
}


uint16_t CurrentDPI(QWidget* widget,int monitor)
{
    float dpi = 1.0;
    int screenNum =  qApp->desktop()->screenNumber(widget);
    qDebug()<<"current screen number is "<<screenNum;
    auto screens = qApp->screens();
    for(int i = 0;i < screens.size();i++){
        if(screenNum >= 0){
            QScreen* screen = qApp->screens().at(i);
            dpi = screen->physicalDotsPerInch();
            qDebug()<<screen->physicalDotsPerInch()<<screen->physicalDotsPerInchX()<<screen->physicalDotsPerInchY();
            qDebug()<<screen->logicalDotsPerInch()<<screen->logicalDotsPerInchX()<<screen->logicalDotsPerInchY();
        }
    }
    return dpi;
}
